// chris 18 Dec 2011
package com.chrishobson.jreedemo.utils;

import static com.chrishobson.jreegl.gl.*;

import com.chrishobson.maths.Vector3D;

/**
 * The camera holds the viewing data. It sets up both the initial modeling
 * matrix and the projection matrix. The Camera is a standard drawable and sets
 * up the view when Draw is called, this means it can be used just like every
 * other drawable and has the added advantage that the viewing transforms are
 * stored in a display list.
 * <p>
 * After Draw has been called the GL_MODELVIEW is left as the active matrix as
 * it is highly unlikely that the projection matrix will ever be changed other
 * than via this class.
 * 
 * @author clh
 * 
 */

public class Camera extends DlDrawable {

  public Camera() {

  }

  public void SetLookAt(Vector3D a_LookAt) {
    m_LookAt.Become(a_LookAt);
    Modified();
  }

  public void SetUp(Vector3D a_Up) {
    m_Up.Become(a_Up);
    Modified();
  }

  public double GetLeft() {
    return m_Left;
  }
  public void SetLeft(double a_Left) {
    m_Left = a_Left;
    Modified();
  }
  public double GetRight() {
    return m_Right;
  }
  public void SetRight(double a_Right) {
    m_Right = a_Right;
    Modified();
  }
  public double GetBottom() {
    return m_Bottom;
  }
  public void SetBottom(double a_Bottom) {
    m_Bottom = a_Bottom;
    Modified();
  }
  public double GetTop() {
    return m_Top;
  }
  public void SetTop(double a_Top) {
    m_Top = a_Top;
    Modified();
  }
  public double GetNear() {
    return m_Near;
  }
  public void SetNear(double a_Near) {
    m_Near = a_Near;
    System.out.println("Near = " + m_Near);
    Modified();
  }
  public double GetFar() {
    return m_Far;
  }
  public void SetFar(double a_Far) {
    m_Far = a_Far;
    System.out.println("Far = " + m_Far);
    Modified();
  }

  public void Render(Renderer a_Renderer) {

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(m_Left, m_Right, m_Bottom, m_Top, m_Near, m_Far);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    gluLookAt(m_LookAt.GetI(), m_LookAt.GetJ(), m_LookAt.GetK(), 0, 0, 0,
        m_Up.GetI(), m_Up.GetJ(), m_Up.GetK());

  }
  /**
   * Model/Viewing
   */
  private Vector3D m_LookAt = new Vector3D();
  private Vector3D m_Up = new Vector3D();
  /**
   * Projection
   */
  double m_Left =-1;
  double m_Right = 1;
  double m_Top = 1;
  double m_Bottom = -1;
  double m_Near = -1;
  double m_Far = 1;
}
